<!DOCTYPE html>
<html>

<head>
    <title>test</title>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
    <meta name="Author" content="阮家友">
    <meta name="Keywords" content="HTML,model,test">
    <meta name="Description" content="special effect">
    <style type="text/css">
        html,
        body {
            font-size: 14px;
            margin: 0px;
            padding: 0px;
        }

        li {
            list-style: none;
        }

        img {
            border: 0px;
        }

        a {
            text-decoration: none;
        }

        .clear {
            clear: both;
        }

        #center {
            width: 800px;
            margin: 0 auto;
            padding-top: 50px;
            position: relative;
        }

        #c1 {
            background-color: #333;
        }
    </style>
</head>

<body>
    <div id="center">
        <canvas id="c1" width="600" height="400px"></canvas><br />
        <button id="btn1">start</button>
        <button id="btn2">stop</button>
        <button id="btn3">clear</button>
    </div>

    <script type="text/javascript">
        //按钮事件
        var ostart = document.getElementById('btn1');
        var ostop = document.getElementById('btn2');
        var oclear = document.getElementById('btn3');
        ostart.onclick = function () {
            obj1.start();
        }
        ostop.onclick = function () {
            obj1.stop();
        }
        oclear.onclick = function () {
            obj1.clear();
        }

        function CreateCanvasObject(canvasId, func) {
            //返回的对象 包含节点Node 绘图环境GC 等属性 和 clear 等方法
            var obj = new Object();
            var ocanvas = document.getElementById(canvasId);
            var ocolor = '';
            if (ocanvas.currentStyle)
                ocolor = ocanvas.currentStyle['backgroundColor'];
            else
                ocolor = getComputedStyle(ocanvas, false)['backgroundColor'];

            //这里要做判断 是否获取到canvas标签 否则返回 null

            //获取画布绘图环境
            var ocanvasGC = ocanvas.getContext('2d');
            obj = {
                Node: ocanvas,
                GC: ocanvasGC,
                timer: '',
                bContinue: false,
                fun: func,
                color: ocolor,
                clear: function () {
                    this.GC.clearRect(0, 0, this.Node.width, this.Node.height);
                },
                start: function () {
                    var oThis = this;
                    if (oThis.timer) {
                        oThis.stop();
                    }
                    oThis.bContinue = true;
                    var loop = function () {
                        oThis.fun(oThis);
                        if (oThis.bContinue) {
                            oThis.timer = setTimeout(loop, 10);
                        }
                    }
                    loop();
                },
                stop: function () {
                    clearTimeout(this.timer);
                    this.bContinue = false;
                }
            }
            return obj;
        }
        //二维向量 可表示位置position(x,y)  速度 v(Vx,Vy) 加速度a(Gx,Gy)
        Vector2 = function (x, y) {
            this.x = x;
            this.y = y;
        };
        var degree = 0;

        Vector2.prototype = {
            copy: function () {
                return new Vector2(this.x, this.y);
            },
            length: function () {
                return Math.sqrt(this.x * this.x + this.y * this.y);
            },
            sqrLength: function () {
                return this.x * this.x + this.y * this.y;
            },
            normalize: function () {
                var inv = 1 / this.length();
                return new Vector2(this.x * inv, this.y * inv);
            },
            negate: function () {
                return new Vector2(-this.x, -this.y);
            },
            add: function (v) {
                return new Vector2(this.x + v.x, this.y + v.y);
            },
            subtract: function (v) {
                return new Vector2(this.x - v.x, this.y - v.y);
            },
            multiply: function (f) {
                return new Vector2(this.x * f, this.y * f);
            },
            divide: function (f) {
                var invf = 1 / f;
                return new Vector2(this.x * invf, this.y * invf);
            },
            dot: function (v) {
                return this.x * v.x + this.y * v.y;
            }
        };

        function draw(obj) {
            //obj.clear();
            //采用叠加递减效果
            obj.GC.fillStyle = "rgba(0,0,0,0.03)";
            obj.GC.fillRect(0, 0, obj.Node.width, obj.Node.height);
            obj.GC.strokeStyle = '#72d6fc';

            var halfW = obj.Node.width / 2;
            var halfH = obj.Node.height / 2;

            //扩散波动圆
            obj.GC.lineWidth = 1;
            for (var k = 0; k < 5; k++) {
                obj.GC.beginPath();
                obj.GC.arc(halfW, halfH, r1 + k, 0, Math.PI * 2, '#72d6fc', true);
                obj.GC.closePath();
                obj.GC.stroke();

                obj.GC.beginPath();
                if (!bFirst)
                    obj.GC.arc(halfW, halfH, r2 + k, 0, Math.PI * 2, '#72d6fc', true);
                obj.GC.closePath();
                obj.GC.stroke();
            }
            if (r1 > R) {
                r1 = 0;
            }
            if (r2 > R) {
                r2 = 0;
                if (bFirst == true) {
                    bFirst = false;
                }
            }
            r1++, r2++;

            //旋转扫描线
            obj.GC.lineWidth = 6;
            obj.GC.save();
            obj.GC.translate(obj.Node.width / 2, obj.Node.height / 2);
            obj.GC.rotate(degree * Math.PI / 180);
            obj.GC.beginPath();
            obj.GC.moveTo(0, -3);
            obj.GC.lineTo(0, R);
            obj.GC.closePath();
            obj.GC.stroke();
            obj.GC.restore();

            //开始画网格
            for (var i = 0; i < obj.Node.width; i += 10) {
                line(obj.GC, '#7266fc', 0.5, i + 0.5, 0, i + 0.5, obj.Node.height);
            }
            for (var j = 0; j < obj.Node.height; j += 10) {
                line(obj.GC, '#7266fc', 0.5, 0, j + 0.5, obj.Node.width, j + 0.5);
            }
            //中心小圆点
            obj.GC.fillStyle = '#c00';
            obj.GC.beginPath();
            obj.GC.arc(halfW, halfH, 4, 0, Math.PI * 2, true);
            obj.GC.closePath();
            obj.GC.fill();

            obj.GC.fillStyle = '#c00';
            obj.GC.beginPath();
            obj.GC.arc(halfW / 2, halfH / 2, 4, 0, Math.PI * 2, true);
            obj.GC.closePath();
            obj.GC.fill();

            degree++;
        }
        //画线方法封装
        function line(gc, color, width, startX, startY, endX, endY) {
            gc.strokeStyle = color;
            gc.lineWidth = width;
            gc.beginPath();
            gc.moveTo(startX, startY);
            gc.lineTo(endX, endY);
            gc.closePath();
            gc.stroke();
        }
        var obj1 = CreateCanvasObject('c1', draw);
        var R = Math.sqrt(Math.pow(obj1.Node.width / 2, 2) + Math.pow(obj1.Node.height / 2, 2));
        var r1 = 0,
            r2 = R / 2,
            bFirst = true;
        //页面打开自动运行
        obj1.start();
        //obj1.stop();
    </script>
</body>

</html>